<?php

namespace App\Repositories;

use Prettus\Repository\Eloquent\BaseRepository;
use Prettus\Repository\Criteria\RequestCriteria;
use App\Repositories\PermissionRepository;
use App\Entities\Permission;
use App\Entities\PermissionRole;
use App\Entities\Role;
use App\Entities\RoleUser;
use App\Validators\PermissionValidator;

class PermissionRepositoryEloquent extends BaseRepository implements PermissionRepository
{
    /**
     * 获取所有权限
     **/
    public function recurrence($pid = 0)
    {
        $recurrence = function($recurrence, $pid) {
            return static::orderBy('sort', 'desc')
                //->findWhere([['pid', '=', $pid], ['is_disabled', '=', 0]])
                ->findWhere([['pid', '=', $pid]])
                ->map(function($item, $index) use ($recurrence, $pid) {
                    $data = [
                        'title' => $item['name'],
                        'id' => $item['id'],
                        'spread' => true,//$item['pid'] == 0,
                    ];
                    if (!static::findWhere([['pid', '=', $pid]], ['id'])) {
                        return $data;
                    }
                    $data['children'] = $recurrence($recurrence, $item['id']);
                    return $data;
                });
        };
        return $recurrence($recurrence, $pid);
    }

    /**
     * 获取用户菜单
     **/
    public function permissions($all = true)
    {
        if ($all) {
            return $this->tree(static::orderBy('sort', 'desc')
                ->findWhere([['is_menu', '=', 1], ['is_disabled' , '=', 0]]));
        }

        $admin = Auth()->guard('admin')->user();
        $role_ids = RoleUser::where('user_id', $admin->id)->pluck('role_id');
        $permission_ids = PermissionRole::whereIn('role_id', $role_ids)
            ->pluck('permission_id');
        return $this->tree(static::model()::whereIn('id', $permission_ids)
            ->where('is_menu', '=', 1)
            ->where('is_disabled', '=', 0)
            ->orderBy('sort', 'desc')
            ->get());
    }

    /**
     * 获取用户拥有的权限
     **/
    public function hasMany($user_id)
    {
        $role_ids = RoleUser::where('user_id', $user_id)->pluck('role_id');
        $permission_ids = PermissionRole::whereIn('role_id', $role_ids)
            ->pluck('permission_id');
        return $this->model->whereIn('id', $permission_ids)
            ->where('route', '<>', '')
            ->where('is_disabled', '=', 0)
            ->pluck('route');
    }

    /**
     * 获取权限树结构
     **/
    protected function tree($collection, $pid = 0)
    {
        $recurrence = function($recurrence, $pid) use ($collection) {
            return $collection->where('pid', $pid)
                ->values()
                ->map(function($item) use ($recurrence, $collection) {
                    $data = [
                        'id' => $item['id'],
                        'pid' => $item['pid'],
                        'title' => $item['name'],
                        'url' => $item['route'] ? url($item['route']) : '',
                        'icon' => $item['icon'],
                    ];
                    if ($collection->where('pid', $item['id'])->isEmpty()) {
                        return $data;
                    }
                    $data['list'] = $recurrence($recurrence, $item['id']);
                    return $data;
            })->toArray();
        };
        return $recurrence($recurrence, $pid);
    }

    /**
     * 格式化权限树
     **/
    public function format()
    {
        $result = [];
        $recurrence = function($recurrence, $data) use (&$result) {
            static $level = 0;
            foreach ($data as $item) {
                array_push($result, [
                    'title' => str_repeat(' ---- ', $level).$item['title'],
                    'value' => $item['id'],
                ]);
                if (isset($item['list'])) {
                    $level ++;
                    $recurrence($recurrence, $item['list']);
                }
            }
            $level -- ;
            return $result;
        };
        return $recurrence($recurrence, $this->permissions('all'));
    }

    public function create(array $data)
    {
        return parent::firstOrCreate($this->transform($data));
    }

    /**
     * 递归创建权限
     */
    public function recurrenceCreate($data)
    {
        $this->model->truncate();
        $recurrence = function($recurrence, $data, $pid) {
            foreach ($data as $item) {
                $created = $this->create([
                    'pid' => $pid,
                    'name' => $item['name'],
                    'is_menu' => @$item['is_menu'] ?: 0,
                    'icon' => @$item['icon'] ?: '',
                    'route' => @$item['url'] ?: '',
                ]);
                if (!@$created->id) {
                    continue;
                }
                if (isset($item['list'])) {
                    $recurrence($recurrence, $item['list'], $created->id);
                }
            }
            return $created->id;
        };
        return $recurrence($recurrence, $data, 0);
    }

    public function update(array $data, $id)
    {
        return parent::update($this->transform($data), $id);
    }

    protected function transform(array $data)
    {
        array_walk($data, function($item, $index) use (&$data) {
            if (is_null($item)) {
                unset($data[$index]);
            }
        });
        return $data;
    }

    /**
     * Specify Model class name
     *
     * @return string
     */
    public function model()
    {
        return Permission::class;
    }

    /**
    * Specify Validator class name
    *
    * @return mixed
    */
    public function validator()
    {
        return PermissionValidator::class;
    }


    /**
     * Boot up the repository, pushing criteria
     */
    public function boot()
    {

    }

}
